package com.example.travelplan.app.dominio;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.List;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.*;


public class Controller {

    private BDados m_dados;
    private Map<Integer, Roteiro> m_mapRoteiro;

    private static Controller instance ;

    private Controller() {
        setM_dados(new BDados());
        m_mapRoteiro = new HashMap<Integer, Roteiro>();
    }

    public static Controller getInstance () {
        if ( Controller.instance == null ) {
            Controller.instance = new Controller();
        }
        return Controller.instance;
    }

    public List<Cidade>  obterListaCidade(){
        Map<Integer,Cidade> mapCidade = this.getM_dados().getM_conjuntoCidade();
        return new ArrayList<Cidade>(mapCidade.values());
    }

    public List<Cidade>  obterListaCidade(String _nome){
        Map<Integer,Cidade> mapCidade = this.getM_dados().getM_conjuntoCidade();

        List<Cidade> listaCidade = new ArrayList<Cidade>();

        if(_nome.isEmpty())
            return listaCidade;

        for (Cidade value : mapCidade.values()) {
            String nomeCidade = value.getM_nome().toUpperCase();
            _nome = _nome.toUpperCase();
            if (value.getM_nome().startsWith(_nome)) {
                listaCidade.add(value);
            }
        }
        return listaCidade;
    }


    public List<TipoLugar> obterTipoLugar(){
        return new ArrayList<TipoLugar>( this.getM_dados().getM_conjuntoTipoLugar().values());
    }

    public TipoLugar obterTipoLugar(int id){
        return this.getM_dados().getM_conjuntoTipoLugar().get(id);
    }

    public List<Roteiro> obterListaRoteiro(){
        if(m_mapRoteiro.isEmpty())
            preencherRoteiroDefault();

        return new ArrayList<Roteiro>(this.m_mapRoteiro.values());
    }

    public void preencherRoteiroDefault()
    {
        m_mapRoteiro =  this.getM_dados().preencherMapRoteiroDefault();
    }

    public BDados getM_dados() {
        return m_dados;
    }

    public void setM_dados(BDados m_dados) {
        this.m_dados = m_dados;
    }

    public List<Roteiro> obterListaRoteiroFavorito(){
        List<Roteiro> listaRoteiro = new ArrayList<Roteiro>();

        for (Roteiro value : m_mapRoteiro.values()) {

            if (value.isM_bFavorito() == true) {
                listaRoteiro.add(value);
            }
        }

        return listaRoteiro;
    }

    public List<Roteiro> obterListaRoteiroAtuais(){

        Map<Date, Roteiro> ordernadoPorData = new HashMap<Date, Roteiro>();
        Date dataAtual = new Date();
        for (Roteiro value : m_mapRoteiro.values()) {
               Date ultimoDia = value.obterDataFinal();
            if (ultimoDia.after(dataAtual)) {
                ordernadoPorData.put(value.getM_dataIda(), value);
            }
        }
        return new ArrayList<Roteiro>(ordernadoPorData.values());
    }


    public List<Roteiro> obterListaRoteiroHistorico(){
        Date dataAtual = new Date();
        List<Roteiro> listaRoteiro= new ArrayList<Roteiro>();

        for (Roteiro value : m_mapRoteiro.values()) {
            Date ultimoDia = value.obterDataFinal();
            if (ultimoDia.before(dataAtual)) {
                listaRoteiro.add(value);
            }
        }

        return listaRoteiro;
    }

    public Roteiro obterRoteiro(int id){
        return m_mapRoteiro.get(id);
    }

    public Cidade obterCidade(Integer _id){
        return m_dados.getCidade(_id);
    }

    public Roteiro obterRoteiroCorrente() {
        return null;
    }

    public int criarRoteiro(Roteiro _roteiro, String[] _tipoLugar){

        Calendar day1 = Calendar.getInstance();
        day1.setTime(_roteiro.getM_dataIda());

        Calendar day2 = Calendar.getInstance();
        day2.setTime(_roteiro.getM_datavolta());

        int from = day1.get(Calendar.DAY_OF_YEAR);
        int to = day2.get(Calendar.DAY_OF_YEAR);

        int difference = to-from;

        int idRoteiro = m_mapRoteiro.size() +1;
        _roteiro.setM_id(idRoteiro);

        List<Lugar> conjuntoLugar = m_dados.getM_conjuntoLugar(_roteiro.getM_cidade().getM_id());

        if(conjuntoLugar.isEmpty()) return -1;

        List<Lugar> listaAuxiliar = new ArrayList<Lugar>(conjuntoLugar) ;

        //criar dias dinamicamente
        Date dataCorrente = _roteiro.getM_dataIda();
        Map<Integer,Dia> conjuntoDias = new HashMap<Integer, Dia>();

        //teste
        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
        SimpleDateFormat sdfHora = new SimpleDateFormat("dd/MM/yyyy hh:mm");

        for(int i = 0; i < difference; i++){

            Dia dia = new Dia();
            dia.setM_id(i+1);
            dia.setM_data(dataCorrente);

            String datestring = sdf.format(dataCorrente);

            if(listaAuxiliar.isEmpty()) listaAuxiliar = new ArrayList<Lugar>(conjuntoLugar);

            Map<Integer,Atividade> conjuntoAtividade = new HashMap<Integer, Atividade>();

            //atividade 1
            Atividade ativ1 = new Atividade();
            ativ1.setM_id(1);
            dataCorrente.setHours(9);
            dataCorrente.setMinutes(0);
            ativ1.setM_data(dataCorrente);

            datestring = sdfHora.format(dataCorrente);

            ativ1.setM_lugar(listaAuxiliar.remove(0));
            conjuntoAtividade.put(1,ativ1);

            if(listaAuxiliar.isEmpty())
                listaAuxiliar = new ArrayList<Lugar>(conjuntoLugar)  ;

            //atividade 2
            Atividade ativ2 = new Atividade();
            ativ2.setM_id(2);
            dataCorrente.setHours(13);
            dataCorrente.setMinutes(0);
            ativ2.setM_data(dataCorrente);
            datestring = sdfHora.format(dataCorrente);
            ativ2.setM_lugar(listaAuxiliar.remove(0));
            conjuntoAtividade.put(2,ativ2);

            if(listaAuxiliar.isEmpty())
                listaAuxiliar = new ArrayList<Lugar>(conjuntoLugar)  ;

            //atividade 3
            Atividade ativ3 = new Atividade();
            ativ3.setM_id(3);
            dataCorrente.setHours(16);
            dataCorrente.setMinutes(0);
            ativ3.setM_data(dataCorrente);
            datestring = sdfHora.format(dataCorrente);
            ativ3.setM_lugar(listaAuxiliar.remove(0));
            conjuntoAtividade.put(3,ativ3);

            dia.setM_atividades(conjuntoAtividade);
            conjuntoDias.put(dia.getM_id(),dia);

            Calendar c = Calendar.getInstance();
            c.setTime(dataCorrente);
            c.add(Calendar.DATE, 1);  // number of days to add
            dataCorrente = c.getTime();
        }

        _roteiro.setM_conjuntoDias(conjuntoDias);
        m_mapRoteiro.put(idRoteiro,_roteiro);

        return idRoteiro;
    }
}